﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace finalProjectGUI
{
    public partial class ClusterDetailsGui : Form
    {
        public ClusterDetailsGui()
        {
            InitializeComponent();
            buttonGeneralView.Text = "View all files distances,\n from this cluster medoid";
        }

        public ZedGraph.ZedGraphControl GraphControl
        {
            get
            {
                return zedGraphControl1;
            }
            set
            {

            }
        }
        private void OnResize()
        {
        }
        private void SetSize()
        {
            zedGraphControl1.Location = new Point(10, 10);
            // Leave a small margin around the outside of the control

            zedGraphControl1.Size = new Size(this.ClientRectangle.Width - (groupBox1.Width+30), this.ClientRectangle.Height - 20);
        }

        private void ClusterDetailsGui_SizeChanged(object sender, EventArgs e)
        {
            SetSize();
        }

        private void ClusterDetailsGui_Load(object sender, EventArgs e)
        {

        }

        public void SetLegend(String legend)
        {
            String[] legendArray = legend.Split('\n');
            listBoxClusteringDetailsLegend.Items.Clear();
            listBoxClusteringDetailsLegend.Items.AddRange(legendArray);
        }

        private void buttonClusteringDetailsPrev_Click(object sender, EventArgs e)
        {
    
            currentClusterIndex = (currentClusterIndex - 1) % clusteringResults.Count;
            if (currentClusterIndex < 0) currentClusterIndex = clusteringResults.Count - 1;
            
            if (buttonGeneralView.Text == "View cluster details")
            {
                createGraph(currentClusterIndex);
            }
            else
            {
                createClusterDetailsGraph(currentClusterIndex);
            }
            this.Refresh();
        }

        private void buttonClusteringDetailsNext_Click(object sender, EventArgs e)
        {
            currentClusterIndex = (currentClusterIndex + 1) % clusteringResults.Count;
             if (buttonGeneralView.Text == "View cluster details")
            {
                createGraph(currentClusterIndex);
            }
            else
            {
                createClusterDetailsGraph(currentClusterIndex);
            }
            this.Refresh();

            
        }
        private int currentClusterIndex = -1;
        private ArrayList clusterIndexes = new ArrayList();
        
        private ArrayList clusteringResults;
        public ArrayList ClusteringResults
        {
          get { return clusteringResults; }
          set { clusteringResults = value; }
        }
        /// <summary>
        /// This method creats the graph that is displayed in this gui
        /// This graph displays the distance of all files from the selected
        /// cluster medoid
        /// </summary>
        /// <param name="selectedIndex">number of the cluster to display</param>
        public void createGraph(int selectedIndex)
        {
            currentClusterIndex = selectedIndex;
            clusterIndexes.Clear();

            if (selectedIndex > -1)
            {
                int clusterNum = 0;
                String lables = "";
                ArrayList distanceFromMedoids = new ArrayList();
                ArrayList clusterSizes = new ArrayList();
                int fileIndex = 1;
                int selectedClusterSize = 0;
                foreach (FinalProjectLogicLayer.DataPoint[] cluster in clusteringResults)
                {
                    clusterNum++;
                    if (cluster.Length > 0) //save the indexs of the clusters
                    {
                        clusterIndexes.Add(clusterNum);
                    }
                    clusterSizes.Add(cluster.Length);
                    for (int i = 0; i < cluster.Length; i++)
                    {
                        lables += fileIndex++ + ": " + cluster[i].SourceFile.Substring(cluster[i].SourceFile.LastIndexOf('\\') + 1) + " - " + cluster[i].Label + "\n\n";
                        if (clusterNum == (selectedIndex + 1))
                        {
                            selectedClusterSize = cluster.Length;
                        }
                        distanceFromMedoids.Add(cluster[i].DistanceFromMedoids[selectedIndex]);
                    }


                }
                int Startindex = 0;
                int endIndex = 0;
                ArrayList allClustersDistances = new ArrayList();

                foreach (int clusterSize in clusterSizes)
                {
                    endIndex = Startindex + clusterSize;
                    double[] distanceArray = new double[distanceFromMedoids.Count]; //create a new array 
                    for (int i = 0; i < distanceFromMedoids.Count; i++)
                    {
                        if (i >= Startindex && i < endIndex)
                            distanceArray[i] = (double)distanceFromMedoids[i];
                        else
                            distanceArray[i] = 0;
                    }
                    allClustersDistances.Add(distanceArray);
                    Startindex = endIndex;
                }

                GuiZedGraph.drawClusterGraph2(zedGraphControl1, (selectedIndex + 1), allClustersDistances);
                this.SetLegend(lables);
            }

        }

        private int indexOfStringInArray(String[] stringArray, String find)
        {
            for (int i = 0; i < stringArray.Length; i++)
            {
                if (stringArray[i] == find)
                    return i;
            }
            return -1;
        }
        /// <summary>
        /// This method creats the graph that is displayed in this gui
        /// This graph displays the distance of all files from the selected
        /// cluster medoid
        /// </summary>
        /// <param name="clusterNumber">number of the cluster to display</param>
        private String[] resultsLables;

        public String[] ResultsLables
        {
            get { return resultsLables; }
            set { resultsLables = value; }
        }
        public void createClusterDetailsGraph(int clusterNumber)
        {
            currentClusterIndex = clusterNumber;
            clusterIndexes.Clear();
            ArrayList clusterDeatilsResultsForGui = new ArrayList(); //this array list will contain int[] for each label;
            if (clusterNumber > -1)
            {
                int clusterNum = 0;
                String lables = "";
                

                int fileIndex = 1;
                String medoidLabel = "";
                foreach (FinalProjectLogicLayer.DataPoint[] cluster in clusteringResults)
                {
                    clusterNum++;
                    if (clusterNum != (clusterNumber+1)) continue; //only the selected cluster is relevent
                    //Create gui ArrayList
                    medoidLabel = cluster[0].Label;
                    clusterDeatilsResultsForGui.Clear(); //Empty first
                    for (int i=0; i<ResultsLables.Length; i++) //Add zeroed array to the array list for gui results
                    {
                        double[] temp = new double[cluster.Length];
                        for (int j = 0; j < temp.Length; j++)
                            temp[j] = 0;
                        clusterDeatilsResultsForGui.Add(temp);
                    }

                    for (int i = 0; i < cluster.Length; i++)
                    {
                        lables += fileIndex++ + ": " + cluster[i].SourceFile.Substring(cluster[i].SourceFile.LastIndexOf('\\') + 1) + "\n";
                        int labelIndex = indexOfStringInArray(ResultsLables, cluster[i].Label);
                        ((double[])clusterDeatilsResultsForGui[labelIndex])[i] = cluster[i].Distance;
                    }
                }

                



                GuiZedGraph.drawClusterGraph2(zedGraphControl1, (clusterNumber + 1), clusterDeatilsResultsForGui,ResultsLables,medoidLabel);
                this.SetLegend(lables);
            }

        }

        private void buttonGeneralView_Click(object sender, EventArgs e)
        {
            if (buttonGeneralView.Text != "View cluster details")
            {
                createGraph(currentClusterIndex);
                buttonGeneralView.Text = "View cluster details";
            }
            else
            {
                createClusterDetailsGraph(currentClusterIndex);
                buttonGeneralView.Text = "View all files distances,\n from this cluster medoid";
            }
            this.Refresh();
        }

    }
}
